﻿using HalconDotNet;
using LeaderCCSLaserUI.Data.Extensions;
using LeaderCCSLaserUI.Models;
using LeaderCCSLaserUI.Services;
using MvCamCtrl.NET.CameraParams;
using Newtonsoft.Json;
using Prism.Commands;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Media;
using ViewROI;
using MessageBox = System.Windows.Forms.MessageBox;

namespace LeaderCCSLaserUI.ViewModels.Dialogs.VisionProgram
{
    public class FunctionShapeModelDialogViewModel : DialogViewModel
    {
        #region 变量
        private HObject mImage;
        private HObject ho_ModelContours;
        private HTuple hv_ModelID;
        private readonly DrawROI drawROI;
        private bool isClosing = false;
        #endregion
        #region 属性
        private HImage cameraImage0;
        public HImage CameraImage0
        {
            get { return cameraImage0; }
            set { SetProperty(ref cameraImage0, value); }
        }
        private HObject cameraAppendHObject0;
        public HObject CameraAppendHObject0
        {
            get { return cameraAppendHObject0; }
            set { SetProperty(ref cameraAppendHObject0, value); }
        }
        private Tuple<string, object> cameraGCStyle0;
        public Tuple<string, object> CameraGCStyle0
        {
            get { return cameraGCStyle0; }
            set { SetProperty(ref cameraGCStyle0, value); }
        }
        private ObservableCollection<ROI> cameraROIList0 = new ObservableCollection<ROI>();
        public ObservableCollection<ROI> CameraROIList0
        {
            get { return cameraROIList0; }
            set { SetProperty(ref cameraROIList0, value); }
        }

        private HMsgEntry cameraAppendHMessage0;
        public HMsgEntry CameraAppendHMessage0
        {
            get { return cameraAppendHMessage0; }
            set { SetProperty(ref cameraAppendHMessage0, value); }
        }

        private GenShapeModelParam mGenShapeModelParam;
        public GenShapeModelParam MGenShapeModelParam
        {
            get { return mGenShapeModelParam; }
            set { SetProperty(ref mGenShapeModelParam, value); }
        }
        private bool isDrawing;
        public bool IsDrawing
        {
            get { return isDrawing; }
            set { SetProperty(ref isDrawing, value); }
        }
        private ShapeModelParamDisp mShapeModelParamDisp;
        public ShapeModelParamDisp MShapeModelParamDisp
        {
            get { return mShapeModelParamDisp; }
            set { SetProperty(ref mShapeModelParamDisp, value); }
        }
        #endregion
        #region 函数
        private DelegateCommand openImageCommand;
        public DelegateCommand OpenImageCommand =>
            openImageCommand ?? (openImageCommand = new DelegateCommand(ExecuteOpenImageCommand));
        private DelegateCommand createShapeModelCommand;
        public DelegateCommand CreateShapeModelCommand =>
            createShapeModelCommand ?? (createShapeModelCommand = new DelegateCommand(ExecuteCreateShapeModelCommand));
        private DelegateCommand saveShapeModelCommand;
        public DelegateCommand SaveShapeModelCommand =>
            saveShapeModelCommand ?? (saveShapeModelCommand = new DelegateCommand(ExecuteSaveShapeModelCommand));
        private DelegateCommand openFileCommand;
        public DelegateCommand OpenFileCommand =>
            openFileCommand ?? (openFileCommand = new DelegateCommand(ExecuteOpenFileCommand));
        private DelegateCommand<object> operateCommandCommand;
        public DelegateCommand<object> OperateCommandCommand =>
            operateCommandCommand ?? (operateCommandCommand = new DelegateCommand<object>(ExecuteOperateCommandCommand));
        private DelegateCommand retateImageCommand;
        public DelegateCommand RetateImageCommand =>
            retateImageCommand ?? (retateImageCommand = new DelegateCommand(ExecuteRetateImageCommand));
        private DelegateCommand actionCommand;
        public DelegateCommand ActionCommand =>
            actionCommand ?? (actionCommand = new DelegateCommand(ExecuteActionCommand));

        void ExecuteActionCommand()
        {
            if (CameraImage0 != null)
            {
                try
                {
                    CameraAppendHObject0 = null;
                    CameraAppendHMessage0 = null;
                    var MShapeModelParam = new ShapeModelParam
                    {
                        NumLevels = MShapeModelParamDisp.NumLevels,
                        AngleStart = MShapeModelParamDisp.AngleStart,
                        AngleEnd = MShapeModelParamDisp.AngleEnd,
                        FileName = MShapeModelParamDisp.FileName,
                        MinScore = MShapeModelParamDisp.MinScore
                    };
                    HTuple row = new HTuple(0), column = new HTuple(0), angle = new HTuple(0), score = new HTuple(0), v1 = new HTuple(0), v2 = new HTuple(0);
                    HObject region, maxRegion;
                    HOperatorSet.GenEmptyObj(out region);
                    HOperatorSet.GenEmptyObj(out maxRegion);
                    var r = MFunc.FunDictionary["ShapeModel"].Run(ref mImage, JsonConvert.SerializeObject(MShapeModelParam, Formatting.Indented), ref row, ref column, ref angle, ref score, ref maxRegion, ref region, ref v1, ref v2);
                    if (r)
                    {
                        CameraGCStyle0 = new Tuple<string, object>("Color", "green");
                        CameraGCStyle0 = new Tuple<string, object>("DrawMode", "margin");
                        CameraAppendHObject0 = region;
                        CameraAppendHMessage0 = new HMsgEntry($"分数:{score.D * 100:f0}\n角度:{angle.TupleDeg().D:f1}°", 10, 10, "magenta", "window", "box", "false", 24, "mono", "true", "false");
                    }
                    else
                    {
                        CameraAppendHMessage0 = new HMsgEntry($"NG", 40, 40, "orange red", "window", "box", "false", 24, "mono", "true", "false");
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                MessageBox.Show("图像不能为空", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        void ExecuteRetateImageCommand()
        {
            if (CameraImage0 != null)
            {
                HOperatorSet.RotateImage(CameraImage0, out mImage, 90, "constant");
                CameraImage0 = new HImage(mImage.CopyObj(1, -1));
            }
            else
            {
                MessageBox.Show("图像不能为空", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        void ExecuteOperateCommandCommand(object obj)
        {
            switch (obj.ToString())
            {
                case "确认":
                    {
                        try
                        {
                            var MShapeModelParam = new ShapeModelParam
                            {
                                NumLevels = MShapeModelParamDisp.NumLevels,
                                AngleStart = MShapeModelParamDisp.AngleStart,
                                AngleEnd = MShapeModelParamDisp.AngleEnd,
                                FileName = MShapeModelParamDisp.FileName,
                                MinScore = MShapeModelParamDisp.MinScore
                            };
                            string jsonString = JsonConvert.SerializeObject(MShapeModelParam, Formatting.Indented);
                            DialogParameters param = new DialogParameters();
                            param.Add("Parameter", jsonString);
                            OnRequestClose(new Prism.Services.Dialogs.DialogResult(ButtonResult.Yes, param));
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                       
                    }
                    break;
                case "取消":
                    OnRequestClose(new Prism.Services.Dialogs.DialogResult(ButtonResult.Cancel));
                    break;
                default:
                    break;
            }
        }
        void ExecuteOpenFileCommand()
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "shm files (*.shm)|*.shm";
            if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                MShapeModelParamDisp.FileName = openFileDialog.FileName;
            }
        }
        void ExecuteSaveShapeModelCommand()
        {
            try
            {
                SaveFileDialog saveFileDialog1 = new SaveFileDialog();
                saveFileDialog1.InitialDirectory = @"C:\";      
                saveFileDialog1.Title = "Save shm Files";
                saveFileDialog1.CheckFileExists = false;
                saveFileDialog1.CheckPathExists = true;
                saveFileDialog1.DefaultExt = "shm";
                saveFileDialog1.Filter = "shm files (*.shm)|*.shm|All files (*.*)|*.*";
                saveFileDialog1.FilterIndex = 1;
                saveFileDialog1.RestoreDirectory = true;
                if (saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    HOperatorSet.WriteShapeModel(hv_ModelID, saveFileDialog1.FileName);
                    string[] strs = saveFileDialog1.FileName.Split("\\");
                    int len = strs[strs.Length - 1].Length;
                    string contoursFileName = saveFileDialog1.FileName.Substring(0, saveFileDialog1.FileName.Length - len) + strs[strs.Length - 1].Replace(".shm", ".dxf");
                    HOperatorSet.WriteContourXldDxf(ho_ModelContours, contoursFileName);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        void ExecuteCreateShapeModelCommand()
        {
            try
            {
                if (CameraImage0 != null)
                {
                    CameraAppendHObject0 = null;
                    CameraAppendHMessage0 = null;
                    IsDrawing = true;
                    var roi = drawROI.imageViewer.DrawROI(ROI.ROI_TYPE_REGION);
                    IsDrawing = false;
                    if (!isClosing)
                    {
                        HRegion ModelRegion = roi.getRegion();
                        HObject TemplateImage;
                        HOperatorSet.ReduceDomain(CameraImage0, ModelRegion, out TemplateImage);
                        HOperatorSet.CreateShapeModel(TemplateImage, MGenShapeModelParam.NumLevels, (new HTuple(MGenShapeModelParam.AngleStart)).TupleRad()
                            , (new HTuple(MGenShapeModelParam.AngleEnd - MGenShapeModelParam.AngleStart)).TupleRad(), (new HTuple(MGenShapeModelParam.AngleStep)).TupleRad(), (new HTuple("point_reduction_high")).TupleConcat(
                            "no_pregeneration"), "ignore_local_polarity", ((new HTuple(MGenShapeModelParam.ThresholdLower)).TupleConcat(
                            MGenShapeModelParam.ThresholdUpper)).TupleConcat(MGenShapeModelParam.Contrast), MGenShapeModelParam.MinContrast, out hv_ModelID);
                        ho_ModelContours.Dispose();
                        HOperatorSet.GetShapeModelContours(out ho_ModelContours, hv_ModelID, 1);
                        HTuple ModelRegionArea, RefRow, RefColumn;
                        HOperatorSet.AreaCenter(ModelRegion, out ModelRegionArea, out RefRow, out RefColumn);
                        HTuple HomMat2D;
                        HOperatorSet.VectorAngleToRigid(0, 0, 0, RefRow, RefColumn, 0, out HomMat2D);
                        HObject TransContours;
                        HOperatorSet.AffineTransContourXld(ho_ModelContours, out TransContours, HomMat2D);
                        
                        CameraGCStyle0 = new Tuple<string, object>("Color", "green");
                        CameraGCStyle0 = new Tuple<string, object>("DrawMode", "margin");
                        CameraAppendHObject0 = TransContours;
                    }
                }
                else
                {
                    MessageBox.Show("图像不能为空", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        void ExecuteOpenImageCommand()
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "Image Files|*.png;*.bmp;*.jpg;*.tif";
            if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (mImage != null)
                {
                    mImage.Dispose();
                }
                HOperatorSet.ReadImage(out mImage, openFileDialog.FileName);
                CameraImage0 = new HImage(mImage.CopyObj(1, -1));
            }
        }
        #endregion
        #region 导航
        public override void OnDialogClosed()
        {
            isClosing = true;
            if (IsDrawing)
            {
                MFunc.HIOCancelDraw();
            }
            if (hv_ModelID != null)
            {
                try
                {
                    HOperatorSet.ClearShapeModel(hv_ModelID);
                }
                catch { }
            }
        }
        public override void OnDialogOpened(IDialogParameters parameters)
        {
            try
            {
                var jsonString = parameters.GetValue<string>("Parameter");
                var _image = parameters.GetValue<HObject>("Image");
                if (_image != null)
                {
                    mImage = _image.CopyObj(1, -1);
                    CameraImage0 = new HImage(mImage.CopyObj(1, -1));
                }
                var MShapeModelParam = JsonConvert.DeserializeObject<ShapeModelParam>(jsonString);
                MShapeModelParamDisp = new ShapeModelParamDisp {
                    NumLevels = MShapeModelParam.NumLevels,
                    AngleStart = MShapeModelParam.AngleStart,
                    AngleEnd = MShapeModelParam.AngleEnd,
                    FileName = MShapeModelParam.FileName,
                    MinScore = MShapeModelParam.MinScore
                };
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                var MShapeModelParam = new ShapeModelParam();
                MShapeModelParam.NumLevels = 3;
                MShapeModelParam.AngleStart = -10;
                MShapeModelParam.AngleEnd = 10;
                MShapeModelParam.FileName = "";
                MShapeModelParam.MinScore = 0.5;
                MShapeModelParamDisp = new ShapeModelParamDisp
                {
                    NumLevels = MShapeModelParam.NumLevels,
                    AngleStart = MShapeModelParam.AngleStart,
                    AngleEnd = MShapeModelParam.AngleEnd,
                    FileName = MShapeModelParam.FileName,
                    MinScore = MShapeModelParam.MinScore
                };
            }
        }
        #endregion
        #region 构造函数
        public FunctionShapeModelDialogViewModel(IContainerProvider containerProvider) : base(containerProvider)
        {
            Title = "模板识别功能";
            MGenShapeModelParam = new GenShapeModelParam {
                NumLevels = 3,
                AngleStart = -10,
                AngleEnd = 10,
                AngleStep = 0.8967,
                ThresholdLower = 54,
                ThresholdUpper = 62,
                Contrast = 7,
                MinContrast = 3
            };
            HOperatorSet.GenEmptyObj(out mImage);
            HOperatorSet.GenEmptyObj(out ho_ModelContours);
            IsDrawing = false;
            drawROI = containerProvider.Resolve<DrawROI>();
        }
        #endregion
        #region 功能函数

        #endregion
    }
}
